package com.nwpu.server.search.controller;


import com.google.gson.Gson;
import com.nwpu.server.common.response.R;
import com.nwpu.server.search.constant.EsConstant;
import com.nwpu.server.search.entity.GeneDiseaseAssociationEntity;
import com.nwpu.server.search.entity.GeneTableEntity;
import com.nwpu.server.search.service.GeneSearchService;
import com.nwpu.server.search.vo.SearchParam;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: YuXingZh
 * @Date: Created in 17:04 2022-03-17
 * @Description:
 */
@RestController
@RequestMapping("search/gene")
public class GeneSearchController {

    @Autowired
    GeneSearchService geneSearchService;

    @Autowired
    public RestHighLevelClient restHighLevelClient;

    /**
     * 查询geneTable
     *
     * @param taskId
     * @return
     */
    @Cacheable(cacheNames = "search", key = "#root.methodName")
    @GetMapping(value = "geneTable/{taskId}")
    @ResponseBody
    public R queryTableByGeneList(@PathVariable("taskId") String taskId) throws IOException {
        List<GeneTableEntity> data = queryByTaskId(taskId);
        return R.ok().put("table", data);
    }

    @Cacheable(cacheNames = "search", key = "#root.methodName")
    public List<GeneTableEntity> queryByTaskId(String taskId) throws IOException {
        // 1.创建查询请求对象
        SearchRequest searchRequest = new SearchRequest(EsConstant.GENE_TABLE_INDEX);
        // 2.构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // (1)查询条件 使用QueryBuilders工具类创建
        // 精确查询
//        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("geneentry", "liuyou");
        //        // 匹配查询
        //        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        // (2)其他<可有可无>：（可以参考 SearchSourceBuilder 的字段部分）
        // 设置高亮
        searchSourceBuilder.highlighter(new HighlightBuilder());
        //        // 分页
        //        searchSourceBuilder.from();
        //        searchSourceBuilder.size();
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//        // (3)条件投入
//        searchSourceBuilder.query(termQueryBuilder);
        // 3.添加条件到请求
        searchRequest.source(searchSourceBuilder);
        // 4.客户端查询请求
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 5.查看返回结果
        SearchHits hits = search.getHits();
        List<GeneTableEntity> data = new ArrayList<>();
        for (SearchHit documentFields : hits.getHits()) {
            Gson gson = new Gson();
            GeneTableEntity geneTableEntity = gson.fromJson(documentFields.getSourceAsString(), GeneTableEntity.class);
            data.add(geneTableEntity);
        }

        return data;
    }


    /**
     * 查询geneTable
     *
     * @param keyword
     * @param gte
     * @param lte
     * @return ans
     */
    @RequestMapping(value = "geneDisease/query")
    public List<String> queryTableByGeneList(@RequestParam(name = "keyword", required = false, defaultValue = "") String keyword,
                                             @RequestParam(name = "gte", required = false, defaultValue = "0.0") double gte,
                                             @RequestParam(name = "lte", required = false, defaultValue = "1.0") double lte) throws IOException {
        List<String> ans = new ArrayList<>();
        SearchParam searchParam = new SearchParam();
        searchParam.setKeyword(keyword);
        SearchRequest searchRequest = new SearchRequest("genedisease");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 关键词模糊搜索
        if (!StringUtils.isEmpty(keyword)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle", keyword));
        }

        // score范围查询
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("score");
        boolean isgte = !StringUtils.isEmpty(gte);
        boolean islte = !StringUtils.isEmpty(lte);
        if (isgte && islte) {
            rangeQueryBuilder.gte(gte).lte(lte);
        } else if (isgte) {
            rangeQueryBuilder.lte(lte);
        } else if (islte) {
            rangeQueryBuilder.gte(gte);
        }


        boolQueryBuilder.filter(rangeQueryBuilder);

        //封装所有的查询条件
        searchSourceBuilder.query(boolQueryBuilder);

        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();

        for (
                SearchHit documentFields : response.getHits().

                getHits()) {
            Gson gson = new Gson();
            GeneDiseaseAssociationEntity geneDiseaseAssociationEntity = gson.fromJson(documentFields.getSourceAsString(), GeneDiseaseAssociationEntity.class);
            ans.add(geneDiseaseAssociationEntity.getDiseasename());
        }

        return ans;
    }
}
